package com.guomei.service.curse.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.guomei.bean.curse.Course;
import com.guomei.bean.curse.CourseVideo;
import com.guomei.bean.curse.UserCourseLearn;
import com.guomei.bean.curse.domain.UserCourseJoin;
import com.guomei.bean.curse.vo.UserCourseJoinVo;
import com.guomei.mapper.curse.CourseMapper;
import com.guomei.mapper.curse.CourseVideoMapper;
import com.guomei.mapper.curse.UserCourseJoinMapper;
import com.guomei.mapper.curse.UserCourseLearnMapper;
import com.guomei.utils.PageData;
import com.guomei.service.curse.UserCourseJoinService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 用户课程参与Service实现类
 */
@Service
@Slf4j
@Transactional
public class UserCourseJoinServiceImpl implements UserCourseJoinService {

    @Resource
    private UserCourseJoinMapper userCourseJoinMapper;

    @Resource
    private UserCourseLearnMapper userCourseLearnMapper;

    @Resource
    private CourseVideoMapper courseVideoMapper;
    
    @Resource
    private CourseMapper courseMapper;

    @Override
    public UserCourseJoin getByUserAndCourse(Long userId, Long courseId) {
        if (userId == null || courseId == null) {
            return null;
        }
        LambdaQueryWrapper<UserCourseJoin> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserCourseJoin::getUserId, userId)
               .eq(UserCourseJoin::getCourseId, courseId);
        return userCourseJoinMapper.selectOne(wrapper);
    }

    @Override
    public List<UserCourseJoin> listByUserId(Long userId) {
        if (userId == null) {
            log.warn("查询用户课程学习记录，用户ID为空");
            return new ArrayList<>();
        }
        LambdaQueryWrapper<UserCourseJoin> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserCourseJoin::getUserId, userId)
               .orderByDesc(UserCourseJoin::getLastLearnTime);
        return userCourseJoinMapper.selectList(wrapper);
    }

    @Override
    public boolean updateCourseProgress(Long userId, Long courseId) {
        if (userId == null || courseId == null) {
            log.warn("更新课程进度参数不完整: userId={}, courseId={}", userId, courseId);
            return false;
        }

        try {
            // 1. 获取该课程的所有视频
            List<CourseVideo> allVideos = courseVideoMapper.selectByCourseId(courseId);
            if (allVideos == null || allVideos.isEmpty()) {
                log.warn("课程{}没有视频，无法更新学习进度", courseId);
                return false;
            }

            // 2. 获取用户对该课程的所有视频学习记录
            List<UserCourseLearn> learnRecords = userCourseLearnMapper.selectByUserAndCourse(userId, courseId);
            if (learnRecords == null || learnRecords.isEmpty()) {
                log.info("用户{}暂无课程{}的学习记录", userId, courseId);
                // 如果没有学习记录，不需要创建UserCourseJoin
                return true;
            }

            // 3. 计算总学习时长
            int totalLearnDuration = learnRecords.stream()
                    .filter(record -> record.getLearnDuration() != null)
                    .mapToInt(UserCourseLearn::getLearnDuration)
                    .sum();

            // 4. 计算课程总时长（所有视频的时长总和）
            int courseTotalDuration = allVideos.stream()
                    .filter(video -> video.getDuration() != null)
                    .mapToInt(CourseVideo::getDuration)
                    .sum();

            // 5. 计算用户已学习的总进度（所有视频的 progress 总和）
            int userTotalProgress = learnRecords.stream()
                    .filter(record -> record.getProgress() != null)
                    .mapToInt(UserCourseLearn::getProgress)
                    .sum();

            // 6. 计算课程学习进度百分比（0-100）
            int courseProgressPercentage = 0;
            if (courseTotalDuration > 0) {
                courseProgressPercentage = (int) Math.min(100, (userTotalProgress * 100.0 / courseTotalDuration));
            }

            // 7. 计算已完成的视频数量（status=1表示已完成）
            long completedVideos = learnRecords.stream()
                    .filter(record -> record.getStatus() != null && record.getStatus() == 1)
                    .count();

            // 8. 判断课程是否完成（所有视频都已完成）
            short courseStatus = (completedVideos == allVideos.size()) ? (short) 1 : (short) 0;

            // 9. 获取最后学习时间
            LocalDateTime lastLearnTime = learnRecords.stream()
                    .filter(record -> record.getLastLearnTime() != null)
                    .map(UserCourseLearn::getLastLearnTime)
                    .max(LocalDateTime::compareTo)
                    .orElse(LocalDateTime.now());

            // 10. 查询是否已存在课程参与记录
            UserCourseJoin existingJoin = getByUserAndCourse(userId, courseId);
            LocalDateTime now = LocalDateTime.now();

            if (existingJoin == null) {
                // 不存在记录，创建新记录
                UserCourseJoin newJoin = new UserCourseJoin();
                newJoin.setUserId(userId);
                newJoin.setCourseId(courseId);
                newJoin.setLearnDuration(totalLearnDuration);
                newJoin.setProgress(courseProgressPercentage); // 存储课程学习进度百分比（0-100）
                newJoin.setStatus(courseStatus);
                newJoin.setLastLearnTime(lastLearnTime);
                newJoin.setCreatedTime(now);
                newJoin.setUpdatedTime(now);

                int inserted = userCourseJoinMapper.insert(newJoin);
                log.info("创建课程学习进度记录: userId={}, courseId={}, 学习时长={}秒, 课程总时长={}秒, 学习进度={}%, 已完成视频数={}/{}, 状态={}", 
                        userId, courseId, totalLearnDuration, courseTotalDuration, courseProgressPercentage, completedVideos, allVideos.size(), courseStatus);
                return inserted > 0;
            } else {
                // 存在记录，更新记录
                existingJoin.setLearnDuration(totalLearnDuration);
                existingJoin.setProgress(courseProgressPercentage); // 存储课程学习进度百分比（0-100）
                existingJoin.setStatus(courseStatus);
                existingJoin.setLastLearnTime(lastLearnTime);
                existingJoin.setUpdatedTime(now);

                int updated = userCourseJoinMapper.updateById(existingJoin);
                log.info("更新课程学习进度记录: userId={}, courseId={}, 学习时长={}秒, 课程总时长={}秒, 学习进度={}%, 已完成视频数={}/{}, 状态={}", 
                        userId, courseId, totalLearnDuration, courseTotalDuration, courseProgressPercentage, completedVideos, allVideos.size(), courseStatus);
                return updated > 0;
            }
        } catch (Exception e) {
            log.error("更新课程学习进度失败: userId={}, courseId={}", userId, courseId, e);
            // 不抛出异常，避免影响主事务
            return false;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveOrUpdate(UserCourseJoin userCourseJoin) {
        if (userCourseJoin == null) {
            return false;
        }

        UserCourseJoin existing = getByUserAndCourse(
                userCourseJoin.getUserId(), 
                userCourseJoin.getCourseId()
        );

        LocalDateTime now = LocalDateTime.now();
        if (existing == null) {
            userCourseJoin.setCreatedTime(now);
            userCourseJoin.setUpdatedTime(now);
            return userCourseJoinMapper.insert(userCourseJoin) > 0;
        } else {
            userCourseJoin.setId(existing.getId());
            userCourseJoin.setUpdatedTime(now);
            return userCourseJoinMapper.updateById(userCourseJoin) > 0;
        }
    }
    
    @Override
    public PageData<UserCourseJoinVo> selectPageWithCourse(UserCourseJoin userCourseJoin) {
        try {
            // 设置分页参数
            int pageNum = userCourseJoin.getPageNum() != null ? userCourseJoin.getPageNum() : 1;
            int pageSize = userCourseJoin.getPageSize() != null ? userCourseJoin.getPageSize() : 10;
            
            // 创建分页对象
            Page<UserCourseJoin> page = new Page<>(pageNum, pageSize);
            
            // 构建查询条件
            LambdaQueryWrapper<UserCourseJoin> wrapper = new LambdaQueryWrapper<>();
            if (userCourseJoin.getUserId() != null) {
                wrapper.eq(UserCourseJoin::getUserId, userCourseJoin.getUserId());
            }
            if (userCourseJoin.getCourseId() != null) {
                wrapper.eq(UserCourseJoin::getCourseId, userCourseJoin.getCourseId());
            }
            if (userCourseJoin.getStatus() != null) {
                wrapper.eq(UserCourseJoin::getStatus, userCourseJoin.getStatus());
            }
            if (userCourseJoin.getProgress() != null) {
                wrapper.ge(UserCourseJoin::getProgress, userCourseJoin.getProgress());
            }
            
            // 按最后学习时间倒序排列
            wrapper.orderByDesc(UserCourseJoin::getLastLearnTime);
            
            // 执行分页查询
            IPage<UserCourseJoin> pageResult = userCourseJoinMapper.selectPage(page, wrapper);
            
            // 转换为VO对象
            List<UserCourseJoinVo> voList = new ArrayList<>();
            for (UserCourseJoin join : pageResult.getRecords()) {
                UserCourseJoinVo vo = new UserCourseJoinVo();
                vo.setUserCourseJoin(join);
                
                // 查询课程信息
                if (join.getCourseId() != null) {
                    Course course = courseMapper.selectById(join.getCourseId());
                    vo.setCourse(course);
                }
                
                voList.add(vo);
            }
            
            // 构建分页结果
            PageData<UserCourseJoinVo> pageData = new PageData<>();
            pageData.setData(voList);
            pageData.setTotal(pageResult.getTotal());
            pageData.setPageNum(pageNum);
            pageData.setPageSize(pageSize);
            
            log.info("分页查询用户课程学习记录成功: 页码={}, 页大小={}, 总数={}", pageNum, pageSize, pageResult.getTotal());
            return pageData;
            
        } catch (Exception e) {
            log.error("分页查询用户课程学习记录失败", e);
            // 返回空的分页结果
            PageData<UserCourseJoinVo> emptyPageData = new PageData<>();
            emptyPageData.setData(new ArrayList<>());
            emptyPageData.setTotal(0L);
            emptyPageData.setPageNum(1);
            emptyPageData.setPageSize(10);
            return emptyPageData;
        }
    }
}

